﻿namespace SimpleWebServices.Web.Mvc
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    using System.Xml;
    using SimpleWebServices.Models;

    public sealed class DebugSubmissionResult : ActionResult
    {
        public DebugSubmissionResult(FormSubmission submission)
        {
            if (null == submission)
            {
                throw new ArgumentNullException("submission");
            }

            this.Submission = submission;
        }

        private FormSubmission Submission
        {
            get;
            set;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (null == context)
            {
                throw new ArgumentNullException("context");
            }

            HttpResponseBase response = context.HttpContext.Response;

            response.Cache.SetCacheability(HttpCacheability.NoCache);

            response.ContentType = "text/html";

            response.AppendHeader("Content-Language", "en");

            using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
            using (XmlTextWriter xml = new XmlTextWriter(writer))
            {
                xml.WriteStartElement("html");
                xml.WriteStartElement("head");
                xml.WriteElementString("title", "Submission Debug View");
                xml.WriteEndElement(); // head
                xml.WriteStartElement("body");
                xml.WriteElementString("h1", "Submission Debug View");

                xml.WriteElementString("h2", "Record");

                xml.WriteStartElement("dl");
                xml.WriteAttributeString("id", "record");

                xml.WriteElementString("dt", "Cacheability");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.cacheability");
                xml.WriteString(this.Submission.Cacheability.HasValue ? string.Empty : this.Submission.Cacheability.Value.ToString("g"));
                xml.WriteEndElement(); // dd
                
                xml.WriteElementString("dt", "Created");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.created");
                xml.WriteString(this.Submission.Created.HasValue ? string.Empty : this.Submission.Created.Value.ToXmlString());
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "ETag");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.etag");
                xml.WriteString(this.Submission.Etag);
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "Expires");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.expires");
                xml.WriteString(this.Submission.Expires);
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "Modified");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.modified");
                xml.WriteString(this.Submission.Modified.HasValue ? string.Empty : this.Submission.Modified.Value.ToXmlString());
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "Status");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.status");
                xml.WriteString(this.Submission.Status.HasValue ? string.Empty : this.Submission.Status.Value.ToString("g"));
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "Token");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.token");
                xml.WriteString(this.Submission.Token.HasValue ? string.Empty : (string)this.Submission.Token.Value);
                xml.WriteEndElement(); // dd

                xml.WriteElementString("dt", "Urn");
                xml.WriteStartElement("dd");
                xml.WriteAttributeString("id", "record.urn");
                xml.WriteString(this.Submission.Urn);
                xml.WriteEndElement(); // dd

                xml.WriteEndElement(); // dl

                xml.WriteElementString("h2", "Data");

                xml.WriteStartElement("dl");
                xml.WriteAttributeString("id", "data");

                if (0 != this.Submission.Data.Count)
                {
                    foreach (var datum in this.Submission.Data)
                    {
                        xml.WriteElementString("dt", datum.Key);
                        xml.WriteStartElement("dd");
                        xml.WriteAttributeString("id", "data." + datum.Key);
                        xml.WriteString(datum.Value);
                        xml.WriteEndElement(); // dd
                    }
                }

                xml.WriteEndElement(); // dl

                xml.WriteElementString("h2", "Metadata");

                xml.WriteStartElement("dl");
                xml.WriteAttributeString("id", "metadata");

                if (0 != this.Submission.Metadata.Count)
                {
                    foreach (var datum in this.Submission.Metadata)
                    {
                        xml.WriteElementString("dt", datum.Name);
                        xml.WriteStartElement("dd");
                        xml.WriteAttributeString("id", "metadata." + datum.Name);
                        xml.WriteString(datum.Content);
                        xml.WriteEndElement(); // dd
                    }
                }

                xml.WriteEndElement(); // dl
                xml.WriteEndElement(); // body
                xml.WriteEndElement(); // html

                xml.Flush();
                writer.Flush();
                response.Write(writer.ToString());
            }
        }
    }
}